home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Tutorial / Cookbook / 28.Motion / MotionView.m < prev    next >
Text File  |  1995-06-12  |  3KB  |  162 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "MotionView.h"
  5. #import <appkit/Form.h>
  6. #import <math.h>
  7. #import <dpsclient/wraps.h>
  8. #import "drawObjects.h"
  9. #import <appkit/Application.h>
  10.  
  11.  
  12. @implementation MotionView
  13.  
  14. void update (teNum, now, myself)
  15. DPSTimedEntry teNum;
  16. double now;
  17. id myself;
  18. {
  19.     [myself doTimedEntry];        
  20. }
  21.  
  22. +newFrame:(const NXRect *)tF {
  23.     self = [super newFrame:tF];
  24.     ballRadius = 8.0;
  25.     ballDiameter = ballRadius*2.0;
  26.     gravity = 0.1;
  27.     angle = 45.0;
  28.     force = 10.0;
  29.     Dx = Dxi = 45.0;    // initial distance
  30.     Dy = Dyi = 25.0;
  31.     trail = 0;
  32.     Vx = Vxi = sin((double) 3.14158/180 * angle) * force;
  33.     Vy = Vyi = cos((double) 3.14158/180 * angle) * force;
  34.     return self;
  35. }
  36.  
  37. - setVxForm:anObject
  38. {
  39.     VxForm = anObject;
  40.     return self;
  41. }
  42.  
  43. - setVyForm:anObject
  44. {
  45.     VyForm = anObject;
  46.     return self;
  47. }
  48.  
  49. - initialize
  50. {
  51.     [self lockFocus]; 
  52.         NXEraseRect(&bounds);
  53.         PSsetgray(NX_BLACK);
  54.     [self unlockFocus];
  55. }
  56.  
  57. - start:sender
  58. {
  59.     if (!running) {
  60.         running = 1;
  61.         clockTE = DPSAddTimedEntry(0.1, &update, self, NX_MODALRESPTHRESHOLD);
  62.     }
  63.     return self;
  64. }
  65.  
  66. - stop:sender
  67. {
  68.     if (running) {
  69.         running = 0;
  70.         DPSRemoveTimedEntry (clockTE);
  71.     }
  72.     return self;
  73. }
  74.  
  75. - reset:sender
  76. {
  77.     if (running) {
  78.         running = 0;
  79.         DPSRemoveTimedEntry (clockTE);
  80.     }
  81.     Dx = Dxi;  Dy = Dxi;
  82.     Vx = Vxi = sin((double) 3.14158/180 * angle) * force;
  83.     Vy = Vyi = cos((double) 3.14158/180 * angle) * force;
  84.     [VxForm setFloatValue:Vxi];
  85.     [VyForm setFloatValue:Vyi];
  86.     [self lockFocus]; 
  87.         NXEraseRect(&bounds);
  88.         PSsetgray(NX_BLACK);
  89.     [self unlockFocus];
  90.  
  91.     [self display];
  92.     return self;
  93. }
  94.  
  95. - doTimedEntry
  96. {
  97.     Dx += Vx;
  98.     Dy += Vy;
  99.  
  100.     [VxForm setFloatValue:Vx];
  101.     [VyForm setFloatValue:Vy];
  102.     
  103.     // acceleration due to gravity    
  104.     Vy -= gravity;
  105.     
  106.     // put in friction
  107.     
  108.     /* handle bouncing off the edges */
  109.     if ((Dx > bounds.size.width - ballRadius) || (Dx < ballRadius)) Vx = -Vx;
  110.     if ((Dy > bounds.size.height - ballRadius) ||(Dy < ballRadius)) Vy = -Vy;
  111.     
  112.     [self display];
  113.     return self;
  114. }
  115.  
  116. // Good programming practice. Free what you create!
  117. - free
  118. {
  119.     [self stop:self];
  120.     return [super free];
  121. }
  122.  
  123. - speed:sender
  124. {
  125.     force = [sender floatValue];
  126.     [self reset:self];
  127.     return self;
  128. }
  129.  
  130. - angle:sender
  131. {
  132.     angle = [sender floatValue];
  133.     [self reset:self];
  134.     return self;
  135. }
  136.  
  137. - gravity:sender
  138. {
  139.     gravity = [sender floatValue];
  140.     [self display];
  141.     return self;
  142. }
  143.  
  144. - trail:sender
  145. {
  146.     trail = [sender intValue];
  147.     [self reset:self];
  148.     return self;
  149. }
  150.  
  151. - drawSelf:(NXRect*)r :(int)c
  152. {
  153.        if (!trail) NXEraseRect(&bounds);
  154.        PSsetgray(NX_BLACK);
  155.     drawPaddle(angle, force);
  156.     doBall(Dx, Dy, ballRadius);
  157.     return self;
  158. }
  159.  
  160.  
  161. @end
  162.